package cn.glc.daily.life.web.service.user.impl;

import cn.glc.daily.life.common.exceptions.GlobalException;
import cn.glc.daily.life.common.utils.JsonResult;
import cn.glc.daily.life.common.utils.JwtUtils;
import cn.glc.daily.life.model.dto.LoginDto;
import cn.glc.daily.life.model.dto.UserSignupDto;
import cn.glc.daily.life.model.to.UserTo;
import cn.glc.daily.life.model.vo.user.UserLoginVo;
import cn.glc.daily.life.model.vo.user.UserVo;
import cn.glc.daily.life.web.convert.*;
import cn.glc.daily.life.web.factory.login.AbstractLoginFactory;
import cn.glc.daily.life.web.service.user.UserService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import static cn.glc.daily.life.common.enums.GlobalCodeEnum.BusinessExceptionEnum.*;
import static cn.glc.daily.life.infrastructure.repository.mysql.MysqlRepositories.*;

/**
 * 用户纯业务
 *
 * @author simon
 * @date 2020/5/28 17:25
 * @copyright:
 * @modifier
 * @motto a no talent, people who have to study hard
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private Map<String, AbstractLoginFactory> abstractLoginFactoryMap;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean signup(UserSignupDto userSignupDto) {
        //查询当前账号是否已经存在
        if (Objects.nonNull(userAuthsRepository.findByIdentifyAndType(userSignupDto.getIdentify(), userSignupDto.getType()))) {
            Optional.empty().orElseThrow(() -> new GlobalException(USER_EXISTS));
        }
        long uid = System.currentTimeMillis();
        //保存用户基础信息
        userRepository.save(UserConvert.INSTANCE.userSignupDtoToUser(userSignupDto, uid));
        //保存用户基础信息（只保存用户名,其他资料走更新）
        userInfoRepository.save(UserInfoConvert.INSTANCE.userSignupDtoToUserInfo(userSignupDto, uid));
        //保存用户登录授权(账号,密码,手机号,邮箱,第三方)
        userAuthsRepository.save(UserAuthsConvert.INSTANCE.userSignupDtoToUserAuths(userSignupDto, uid));
        //保存用户默认角色
        userRoleRepository.save(UserRoleConvert.INSTANCE.ordinary(uid));
        //保存用户默认权限
//        userRoleRepository.save(UserRoleConvert.INSTANCE.ordinary(uid));
        return true;
    }

    @Override
    public UserVo findDetailsByUid(Long uId) {
        UserTo details = userRepository.findDetailsByUid(uId);
        return UserConvert.INSTANCE.userToUserVo(details);
    }

    @Override
    public Boolean accountClose(Long uId) {
        UserVo userVo = findDetailsByUid(uId);
        if (Objects.nonNull(userVo)) {
            return userRepository.accountClose(userVo.getUid());
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JsonResult unifiedLogin(LoginDto loginDto) {
        if (Objects.isNull(loginDto.getType())) {
            throw new GlobalException(LOGIN_TYPE_EXCEPTION);
        }
        Long uid = Optional.ofNullable(abstractLoginFactoryMap.get(loginDto.getType().getValue()).login(loginDto))
                .orElseThrow(() -> new GlobalException(LOGIN_FAIL));
        UserVo userVo = findDetailsByUid(uid);
        String sign = JwtUtils.sign(JSON.toJSONString(JwtUserConvert.INSTANCE.userVo2JwtUserDetail(userVo)), loginDto.getCredential());
        return JsonResult.returnSuccess(UserLoginVo.builder().uid(uid).token(sign).build());
    }
}
